from fastapi import APIRouter, HTTPException
from config import Config
from utils import analyze_data, TrendAnalyzer, should_include_analysis, should_include_chart, convert_params, get_user_available_units, service, chat_history_manager, LLMService
from models import UserRequest, UnitDateParams
import logging
import uuid
import time
import asyncio
import aiofiles
from typing import Optional, List, Dict
import json
from datetime import datetime, timedelta

# 大模型理解用户选择的函数
async def _llm_understand_selection(history_content: str, selection_index: int, available_units: List[Dict]) -> Optional[Dict]:
    """
    使用大模型理解历史对话中的序号对应关系
    
    Args:
        history_content: 历史对话内容
        selection_index: 用户选择的序号（0开始）
        available_units: 可用的单位列表
        
    Returns:
        匹配的单位信息字典，如果未找到则返回None
    """
    try:
        # 构建提示词
        prompt = f"""请根据以下对话历史，理解用户选择的序号对应的单位信息。

对话历史：
{history_content}

用户选择了第 {selection_index + 1} 个选项。

可用的单位列表：
{json.dumps(available_units, ensure_ascii=False, indent=2)}

请从可用单位列表中找出用户选择的单位，返回对应的完整单位信息。
如果找不到匹配的单位，请返回null。

请直接返回JSON格式的单位信息，不要添加任何解释。"""

        # 调用LLM服务
        response = await LLMService.call_qwen_model(prompt, temperature=0.0, timeout=30)
        
        # 解析响应
        if response and response.strip():
            try:
                # 尝试解析JSON响应
                unit_info = json.loads(response.strip())
                if isinstance(unit_info, dict) and unit_info.get('unitId'):
                    return unit_info
            except json.JSONDecodeError:
                logging.warning(f"LLM返回的响应不是有效的JSON格式: {response}")
        
        return None
        
    except Exception as e:
        logging.error(f"大模型理解用户选择失败: {str(e)}")
        return None

# 验证发票时间范围匹配逻辑
async def _validate_invoice_date_matching(data: dict, params: dict) -> None:
    """
    验证发票时间范围匹配逻辑
    检查发票的结束时间是否在用户查询的月份区间内（使用转换后的实际查询参数）
    """
    try:
        invoice_list = data.get('invoiceList', [])
        
        # 获取查询的时间范围（使用转换后的实际查询参数）
        query_start_date = params.get('startDate', '')
        query_end_date = params.get('endDate', '')
        
        # 记录查询参数信息，即使发票列表为空
        logging.info(f"[月份范围验证] 转换后的实际查询时间范围: {query_start_date} 至 {query_end_date}")
        logging.info(f"[月份范围验证] 发票记录数量: {len(invoice_list)}条")
        
        if not invoice_list:
            logging.info(f"[月份范围验证] 发票列表为空，跳过详细验证")
            return
            
        if not query_start_date or not query_end_date:
            logging.warning(f"[月份范围验证] 查询时间参数不完整，跳过验证")
            return
            
        # 提取查询的月份范围（正确处理YYYYMMDD格式）
        # 对于YYYYMMDD格式，取前6位作为月份（YYYYMM）
        query_start_month = query_start_date[:6] if len(query_start_date) >= 6 else ''
        query_end_month = query_end_date[:6] if len(query_end_date) >= 6 else ''
        
        if not query_start_month or not query_end_month:
            logging.warning(f"[月份范围验证] 无法提取查询月份范围，跳过验证")
            return
            
        logging.info(f"[月份范围验证] 转换后的实际查询月份区间: {query_start_month} 至 {query_end_month}")
        logging.info(f"[月份范围验证] 验证规则: 仅检查发票结束月份是否在查询月份区间内（忽略开始日期）")
            
        # 检查发票的结束时间是否在查询的月份区间内
        invoices_outside_month_range = []
        invoices_inside_month_range = []
        
        for invoice in invoice_list:
            invoice_end_date = invoice.get('endDate', '')
            if invoice_end_date and len(invoice_end_date) >= 6:
                # 发票结束日期可能是YYYYMM或YYYYMMDD格式，统一取前6位作为月份
                invoice_end_month = invoice_end_date[:6]
                
                # 检查结束月份是否在查询月份区间内（使用转换后的实际查询参数）
                # 注意：这里比较的是月份字符串（YYYYMM格式），需要确保格式一致
                if invoice_end_month < query_start_month or invoice_end_month > query_end_month:
                    invoices_outside_month_range.append({
                        'endDate': invoice_end_date,
                        'endMonth': invoice_end_month,
                        'amountWithTax': invoice.get('amountWithTax', '0')
                    })
                else:
                    invoices_inside_month_range.append({
                        'endDate': invoice_end_date,
                        'endMonth': invoice_end_month,
                        'amountWithTax': invoice.get('amountWithTax', '0')
                    })
        
        # 记录验证结果
        logging.info(f"[月份范围验证] 在转换后查询月份区间内的发票数量: {len(invoices_inside_month_range)}")
        logging.info(f"[月份范围验证] 不在转换后查询月份区间内的发票数量: {len(invoices_outside_month_range)}")
        
        if invoices_outside_month_range:
            logging.warning(f"[月份范围验证] 发现{len(invoices_outside_month_range)}张发票的结束月份不在转换后查询月份区间内")
            for invoice in invoices_outside_month_range[:3]:  # 只显示前3条
                logging.warning(f"[月份范围验证] 发票结束月份: {invoice['endMonth']}, 金额: {invoice['amountWithTax']}")
            
            # 记录详细的验证信息
            logging.info(f"[月份范围验证] 当前验证规则: 仅检查发票结束月份是否在查询月份区间内（忽略开始日期）")
        
        if invoices_inside_month_range:
            logging.info(f"[月份范围验证] 发现{len(invoices_inside_month_range)}张发票的结束月份在转换后查询月份区间内")
            for invoice in invoices_inside_month_range[:3]:  # 只显示前3条
                logging.info(f"[月份范围验证] 匹配发票结束月份: {invoice['endMonth']}, 金额: {invoice['amountWithTax']}")
            
    except Exception as e:
        logging.error(f"[月份范围验证] 验证发票月份范围匹配失败: {str(e)}")

# 处理发票数据
async def process_invoice_data(data: dict, debug: bool, user_query: str, params: dict, conversation_id: Optional[str] = None, include_analysis: Optional[bool] = None, include_chart: Optional[bool] = None, include_cross_month: Optional[bool] = None) -> dict:
    start_time = time.time()
    logging.info(f"[步骤5-发票数据处理] 开始处理发票数据")
    
    # 不再进行额外的日期验证，直接使用接口返回的数据
    logging.info(f"[数据处理] 直接使用接口返回的数据，不进行额外过滤")
    
    if data.get('respCode') != '00':
        logging.error(f"[API错误] 发票查询失败: {data.get('respMsg')}")
        # 检查是否是权限错误
        error_msg = data.get('respMsg', '未知错误')
        if "权限" in error_msg or "没有权限" in error_msg or "无权" in error_msg:
            # 获取用户可以查询的单位列表
            try:
                from utils import get_user_available_units
                # 从params中获取手机号
                phone_number = params.get('phoneNo', '')
                if phone_number:
                    available_units = await get_user_available_units(phone_number)
                    if available_units:
                        raise HTTPException(status_code=403, detail=f"您没有权限查询此单位，请去统一对账平台进行绑定。您可以查询的单位有：{', '.join(available_units)}")
                    else:
                        # 无单位时返回空结果而不是错误
                        return {
                            "type": "invoice_list",
                            "result": {
                                "answer": "您的微信手机号未绑定到任何清算单位或商户，请联系您的客户经理，完成绑定后可使用本清算智能体的功能。",
                                "conversation_id": conversation_id
                            },
                            "conversation_id": conversation_id,
                            "raw_data": None if not debug else {
                                "user_query": user_query,
                                "conversation_id": conversation_id,
                                "available_units": available_units
                            }
                        }
                else:
                    raise HTTPException(status_code=403, detail="您没有权限查询此单位，请去统一对账平台进行绑定。")
            except HTTPException:
                # 重新抛出HTTPException
                raise
            except Exception as e:
                logging.error(f"获取用户可用单位失败: {str(e)}")
                raise HTTPException(status_code=403, detail="您没有权限查询此单位，请去统一对账平台进行绑定。")
        else:
            raise HTTPException(status_code=400, detail=f"查询失败：{error_msg}")

    invoice_list = data.get('invoiceList', [])
    result_count = data.get('resultCount', len(invoice_list))
    logging.info(f"[数据处理] 发票记录数量: {result_count}条")

    # 获取查询日期范围
    start_date = params.get('startDate')
    end_date = params.get('endDate')

    # 获取发票数据后，需要扩展查询时间范围来检测跨月记录
    # 因为API只返回完全在查询时间范围内的记录，所以需要扩展范围来获取可能跨月的记录
    extended_start_date = start_date
    extended_end_date = end_date
    
    # 如果查询的是单月数据，扩展到前后一个月以检测跨月记录
    try:
        start_date_obj = datetime.strptime(start_date, "%Y%m%d")
        end_date_obj = datetime.strptime(end_date, "%Y%m%d")
        
        # 如果查询范围在一个月内，扩展到前后一个月
        if start_date_obj.month == end_date_obj.month and start_date_obj.year == end_date_obj.year:
            # 扩展到前一个月的第一天和后一个月的最后一天
            if start_date_obj.month == 1:
                prev_month_start = datetime(start_date_obj.year-1, 12, 1)
            else:
                prev_month_start = datetime(start_date_obj.year, start_date_obj.month-1, 1)
                
            if end_date_obj.month == 12:
                next_month_end = datetime(end_date_obj.year+1, 1, 1)
                # 获取下个月的最后一天
                next_month_end = datetime(next_month_end.year, next_month_end.month+1, 1) - timedelta(days=1)
            else:
                next_month_end = datetime(end_date_obj.year, end_date_obj.month+2, 1) - timedelta(days=1)
            
            extended_start_date = prev_month_start.strftime("%Y%m%d")
            extended_end_date = next_month_end.strftime("%Y%m%d")
            
            logging.info(f"[跨月记录检测] 扩展查询时间范围: {extended_start_date} 至 {extended_end_date}")
    except Exception as e:
        logging.error(f"[跨月记录检测] 扩展时间范围失败: {str(e)}")
        # 如果扩展失败，使用原始时间范围
        extended_start_date = start_date
        extended_end_date = end_date
    
    # 只有在时间范围被扩展的情况下才重新查询API
    extended_invoice_list = invoice_list
    if extended_start_date != start_date or extended_end_date != end_date:
        try:
            # 使用扩展后的时间范围重新查询API以获取可能的跨月记录
            extended_params = params.copy()
            extended_params['startDate'] = extended_start_date
            extended_params['endDate'] = extended_end_date
            
            extended_data = await service.call_api(Config.INVOICE_API_PATH, extended_params)
            if isinstance(extended_data, dict):
                extended_invoice_list = extended_data.get('invoiceList', [])
                logging.info(f"[跨月记录检测] 扩展查询获取到{len(extended_invoice_list)}条记录")
            else:
                logging.error(f"[跨月记录检测] 扩展查询API返回类型错误")
        except Exception as e:
            logging.error(f"[跨月记录检测] 扩展查询失败: {str(e)}")
    
    # 筛选查询时间段的记录
    # 使用发票本身的日期范围进行筛选
    filtered_invoice_list = []
    cross_month_invoice_list = []  # 存储跨月的发票记录
    
    if start_date and end_date:
        # 首先筛选完全在查询时间范围内的记录
        filtered_invoice_list = [
            item for item in extended_invoice_list
            if item.get('endDate', '') >= start_date and item.get('endDate', '') <= end_date
        ]
        
        # 然后找出跨月但与查询时间范围有交集的记录
        cross_month_invoice_list = []
        for item in extended_invoice_list:
            # 跳过已经在filtered_invoice_list中的记录
            if item in filtered_invoice_list:
                continue
                
            item_start = item.get('startDate', '')
            item_end = item.get('endDate', '')
            
            # 检查是否是跨月记录：发票记录的时间范围跨越了查询时间范围的边界
            is_cross_month = False
            try:
                # 检查发票记录是否跨越查询时间范围的边界
                # 真正的跨月记录应该是：发票开始日期在查询时间范围之前，结束日期在查询时间范围之后
                # 或者发票记录的时间范围与查询时间范围有部分重叠
                
                # 将日期字符串转换为日期对象进行比较
                item_start_date = datetime.strptime(item_start, "%Y%m%d") if item_start else None
                item_end_date = datetime.strptime(item_end, "%Y%m%d") if item_end else None
                query_start_date_obj = datetime.strptime(start_date, "%Y%m%d")
                query_end_date_obj = datetime.strptime(end_date, "%Y%m%d")
                
                if item_start_date and item_end_date:
                    # 情况1：发票记录完全跨越查询时间范围（开始日期在查询之前，结束日期在查询之后）
                    if item_start_date < query_start_date_obj and item_end_date > query_end_date_obj:
                        is_cross_month = True
                    # 情况2：发票记录开始日期在查询之前，结束日期在查询范围内
                    elif item_start_date < query_start_date_obj and query_start_date_obj <= item_end_date <= query_end_date_obj:
                        is_cross_month = True
                    # 情况3：发票记录开始日期在查询范围内，结束日期在查询之后
                    elif query_start_date_obj <= item_start_date <= query_end_date_obj and item_end_date > query_end_date_obj:
                        is_cross_month = True
                    # 情况4：发票记录与查询时间范围有部分重叠（开始日期在查询之前，结束日期在查询之后）
                    elif item_start_date <= query_end_date_obj and item_end_date >= query_start_date_obj:
                        is_cross_month = True
                        
            except Exception as e:
                logging.warning(f"[跨月记录检测] 日期解析失败: {str(e)}")
                # 如果日期解析失败，使用简单的字符串比较作为备选方案
                if item_start and item_end:
                    # 简单的字符串比较：检查发票记录是否跨越查询边界
                    if (item_start < start_date and item_end > end_date) or \
                       (item_start < start_date and start_date <= item_end <= end_date) or \
                       (start_date <= item_start <= end_date and item_end > end_date) or \
                       (item_start <= end_date and item_end >= start_date):
                        is_cross_month = True
            
            # 如果是跨月记录，添加到跨月记录列表
            if is_cross_month:
                cross_month_invoice_list.append(item)
    else:
        filtered_invoice_list = extended_invoice_list

    result_count = len(filtered_invoice_list)
    cross_month_count = len(cross_month_invoice_list)
    logging.info(f"[数据处理] 筛选后发票记录数量: {result_count}条")
    logging.info(f"[数据处理] 跨月发票记录数量: {cross_month_count}条")

    # 获取单位名称
    unit_name = "未知"
    try:
        # 从params中获取手机号和单位ID
        phone_number = params.get('phoneNo', '')
        unit_id = params.get('unitId', '')
        logging.info(f"[单位名称获取] 开始获取单位名称，手机号: {phone_number}, 单位ID: {unit_id}")
        
        if phone_number and unit_id:
            # 获取用户可查询单位列表
            from utils import get_user_available_units, safe_extract_unit_name
            available_units = await get_user_available_units(phone_number, return_full_info=True)
            logging.info(f"[单位名称获取] 获取到可查询单位数量: {len(available_units)}")
            
            # 查找匹配的单位名称
            for unit in available_units:
                if isinstance(unit, dict) and unit.get('unitId') == unit_id:
                    unit_name = safe_extract_unit_name(unit)
                    logging.info(f"[单位名称获取] 成功从单位列表中获取到单位名称: {unit_name}")
                    break
            else:
                logging.warning(f"[单位名称获取] 未在可查询单位列表中找到匹配的单位ID: {unit_id}")
                # 尝试从发票数据中获取单位名称
                if invoice_list and isinstance(invoice_list[0], dict):
                    # 尝试从发票数据中提取单位相关信息
                    company_id = invoice_list[0].get('companyId')
                    if company_id:
                        unit_name = f"统一结算单位号: {company_id}"
                        logging.info(f"[单位名称获取] 从发票数据中获取到单位信息: {unit_name}")
                
                # 如果仍未获取到单位名称，尝试使用第一个可查询单位作为备选
                if unit_name == "未知" and available_units:
                    try:
                        first_unit = available_units[0]
                        unit_name = safe_extract_unit_name(first_unit)
                        logging.info(f"[单位名称获取] 使用第一个可查询单位作为备选名称: {unit_name}")
                    except Exception as e:
                        logging.error(f"[单位名称获取] 获取第一个可查询单位名称失败: {str(e)}")
        else:
            logging.warning(f"[单位名称获取] 缺少必要参数，手机号: {phone_number}, 单位ID: {unit_id}")
            # 如果缺少参数，尝试使用第一个可查询单位作为备选
            if phone_number:
                try:
                    from utils import get_user_available_units, safe_extract_unit_name
                    available_units = await get_user_available_units(phone_number, return_full_info=True)
                    if available_units:
                        first_unit = available_units[0]
                        unit_name = safe_extract_unit_name(first_unit)
                        logging.info(f"[单位名称获取] 缺少参数时使用第一个可查询单位作为备选: {unit_name}")
                except Exception as e:
                    logging.error(f"[单位名称获取] 获取第一个可查询单位名称失败: {str(e)}")
    except Exception as e:
        logging.error(f"获取单位名称失败: {str(e)}")
        unit_name = "未知"

    # 智能判断是否需要数据分析和趋势图
    do_analysis = include_analysis if include_analysis is not None else should_include_analysis(user_query, "invoice")
    do_chart = include_chart if include_chart is not None else should_include_chart(user_query, "invoice")
    
    # 构建竖向Markdown表格格式的结果
    # 确定实际查询的时间范围（可能是扩展后的）
    actual_start_date = extended_start_date if extended_start_date != start_date else start_date
    actual_end_date = extended_end_date if extended_end_date != end_date else end_date
    
    if result_count == 0 and cross_month_count == 0:
        # 记录查询参数信息，帮助调试
        query_start_date = params.get('startDate', '')
        query_end_date = params.get('endDate', '')
        query_unit_id = params.get('unitId', '')
        
        logging.info(f"[发票查询] 查询参数详情:")
        logging.info(f"[发票查询] - 时间范围: {query_start_date} 至 {query_end_date}")
        logging.info(f"[发票查询] - 单位ID: {query_unit_id}")
        logging.info(f"[发票查询] - 响应码: {data.get('respCode', '未知')}")
        
        result_lines = [f"### 未找到符合条件的发票记录"]
    elif result_count == 0 and cross_month_count > 0:
        # 只有跨月记录的情况
        result_lines = [f"### 查询完成，在指定时间范围（{start_date}至{end_date}）内未找到发票记录，但发现{cross_month_count}条跨月记录可能相关："]
        result_lines.append("\n跨月记录列表：")
        
        # 构建跨月记录的简要信息
        for idx, invoice in enumerate(cross_month_invoice_list, 1):
            invoice_no = invoice.get('invoiceNo', '未知')
            invoice_end_date = invoice.get('endDate', '未知')
            amount_with_tax = invoice.get('amountWithTax', '0')
            result_lines.append(f"{idx}. 发票编号：{invoice_no}，结束日期：{invoice_end_date}，含税金额：{amount_with_tax}元")
        
        result_lines.append("\n是否需要包含这些跨月记录？请回复'是'或'否'")
    elif result_count > 0 and cross_month_count > 0:
        # 既有正常记录又有跨月记录的情况
        result_lines = [f"### 查询成功，共找到{result_count}条发票记录（{start_date}至{end_date}），另外还有{cross_month_count}条跨月记录可能相关："]
        result_lines.append("\n#### 跨月记录列表：")
        
        # 构建跨月记录的简要信息
        for idx, invoice in enumerate(cross_month_invoice_list, 1):
            invoice_no = invoice.get('invoiceNo', '未知')
            invoice_end_date = invoice.get('endDate', '未知')
            amount_with_tax = invoice.get('amountWithTax', '0')
            result_lines.append(f"{idx}. 发票编号：{invoice_no}，结束日期：{invoice_end_date}，含税金额：{amount_with_tax}元")
        
        result_lines.append("\n是否需要包含这些跨月记录？请回复'是'或'否'")
    elif result_count > 0 and cross_month_count == 0:
        # 只有正常记录的情况
        result_lines = [f"### 查询成功，共找到{result_count}条发票记录（{start_date}至{end_date}）"]
    
    # 如果用户要求数据分析，则显示数据分析模式的提示信息
    if do_analysis or do_chart:
        result_lines = [f"### 数据分析结果"]
    
    # 创建独立的记录数组
    records = []
    download_links = []
    
    # 处理正常记录（filtered_invoice_list）
    for idx, invoice in enumerate(filtered_invoice_list, 1):
        # 提取当前发票的PDF链接
        pdf_url = invoice.get('pdfUrl')
        
        # 将http链接转换为https链接
        if pdf_url and pdf_url.startswith('http://'):
            pdf_url = pdf_url.replace('http://', 'https://', 1)
        
        # 将下载链接添加到列表
        download_links.append({
            'index': idx,
            'download_url': pdf_url,
            'file_type': 'pdf'
        })
        
        # 构建单条记录的完整内容
        record_content = []
        record_content.append(f"#### 第{idx}条发票记录")
        record_content.append(f"| 序号 | {idx} |")
        record_content.append("|------|-----|")
        record_content.append(f"| 单位名称 | {unit_name} |")
        record_content.append(f"| 开票结束日期 | {invoice.get('endDate', '未知')} |")
        record_content.append(f"| 含税金额(元) | {invoice.get('amountWithTax', '0')} |")
        record_content.append(f"| 不含税金额(元) | {invoice.get('amount', '0')} |")
        record_content.append(f"| 税额(元) | {invoice.get('taxAmount', '0')} |")
        
        # 将完整记录内容作为单个字符串添加到records数组
        records.append("\n".join(record_content))

    # 准备结果变量
    trend_data = None
    text_analysis = None
    
    # 根据判断结果决定是否执行数据分析和趋势图生成
    if do_analysis or do_chart:
        tasks = []
        
        if do_chart:
            # 创建趋势图生成任务
            trend_task = asyncio.create_task(
                asyncio.to_thread(
                    TrendAnalyzer.generate_trend_chart,
                    data_list=invoice_list,
                    date_field='endDate',
                    value_field='amountWithTax',
                    title=f'{unit_name}含税金额趋势分析',
                    x_label='日期',
                    y_label='金额(元)',
                    value_converter=lambda x: float(x),
                    analysis_type="invoice"
                )
            )
            tasks.append(('chart', trend_task))
        
        if do_analysis:
            # 创建文本数据分析任务
            analysis_task = asyncio.create_task(
                analyze_data(data, analysis_type="invoice")
            )
            tasks.append(('analysis', analysis_task))
        
        # 等待所有任务完成
        if tasks:
            done, pending = await asyncio.wait([task for _, task in tasks], return_when=asyncio.ALL_COMPLETED)
            
            for task_type, task in tasks:
                if task in done:
                    try:
                        result = task.result()
                        if task_type == 'chart':
                            trend_data = result
                            logging.info(f"[趋势分析] 生成发票金额趋势图成功")
                        elif task_type == 'analysis':
                            text_analysis = result
                    except Exception as e:
                        if task_type == 'chart':
                            logging.error(f"[趋势分析] 生成趋势图失败: {str(e)}")
                        elif task_type == 'analysis':
                            logging.error(f"[数据分析] 分析失败: {str(e)}")

    # 使用传入的conversation_id
    logging.info(f"[对话管理] 使用传入的conversation_id: {conversation_id}")

    # 检查是否需要包含跨月记录
    # 优先使用传入的include_cross_month参数，如果没有则使用params中的设置
    include_cross_month = include_cross_month if include_cross_month is not None else params.get('include_cross_month', False)
    
    # 如果用户确认包含跨月记录，将跨月记录合并到正常记录中
    if include_cross_month and cross_month_count > 0:
        # 将跨月记录添加到正常记录中，保持与正常记录相同的格式
        for idx, invoice in enumerate(cross_month_invoice_list, len(filtered_invoice_list) + 1):
            # 构建跨月记录的完整内容，格式与正常记录保持一致
            record_content = []
            record_content.append(f"#### 第{idx}条发票记录（跨月）")
            record_content.append(f"| 序号 | {idx} |")
            record_content.append("|------|-----|")
            record_content.append(f"| 单位名称 | {unit_name} |")
            record_content.append(f"| 开票结束日期 | {invoice.get('endDate', '未知')} |")
            record_content.append(f"| 含税金额(元) | {invoice.get('amountWithTax', '0')} |")
            record_content.append(f"| 不含税金额(元) | {invoice.get('amount', '0')} |")
            record_content.append(f"| 税额(元) | {invoice.get('taxAmount', '0')} |")
            
            # 将完整记录内容作为单个字符串添加到records数组
            records.append("\n".join(record_content))
        
        # 更新记录数量
        total_count = len(records)
        
        # 重新构建摘要信息，包含跨月记录的完整结果
        result_lines = [f"### 查询成功，共找到{total_count}条发票记录（包含{cross_month_count}条跨月记录）"]
        
        # 为跨月记录也添加下载链接
        for idx, invoice in enumerate(cross_month_invoice_list, len(filtered_invoice_list) + 1):
            # 提取当前发票的PDF链接
            pdf_url = invoice.get('pdfUrl')
            
            # 将http链接转换为https链接
            if pdf_url and pdf_url.startswith('http://'):
                pdf_url = pdf_url.replace('http://', 'https://', 1)
            
            # 将下载链接添加到列表
            download_links.append({
                'index': idx,
                'download_url': pdf_url,
                'file_type': 'pdf'
            })
    else:
        # 正常查询流程，根据记录情况构建result_lines
        if result_count == 0 and cross_month_count == 0:
            # 记录查询参数信息，帮助调试
            query_start_date = params.get('startDate', '')
            query_end_date = params.get('endDate', '')
            query_unit_id = params.get('unitId', '')
            
            logging.info(f"[发票查询] 查询参数详情:")
            logging.info(f"[发票查询] - 时间范围: {query_start_date} 至 {query_end_date}")
            logging.info(f"[发票查询] - 单位ID: {query_unit_id}")
            logging.info(f"[发票查询] - 响应码: {data.get('respCode', '未知')}")
            
            result_lines = [f"### 未找到符合条件的发票记录"]
        elif result_count == 0 and cross_month_count > 0:
            # 只有跨月记录的情况
            result_lines = [f"### 查询完成，在指定时间范围（{start_date}至{end_date}）内未找到发票记录，但发现{cross_month_count}条跨月记录可能相关："]
            result_lines.append("\n跨月记录列表：")
            
            # 构建跨月记录的简要信息
            for idx, invoice in enumerate(cross_month_invoice_list, 1):
                invoice_no = invoice.get('invoiceNo', '未知')
                invoice_end_date = invoice.get('endDate', '未知')
                amount_with_tax = invoice.get('amountWithTax', '0')
                result_lines.append(f"{idx}. 发票编号：{invoice_no}，结束日期：{invoice_end_date}，含税金额：{amount_with_tax}元")
            
            result_lines.append("\n是否需要包含这些跨月记录？请回复'是'或'否'")
        elif result_count > 0 and cross_month_count > 0:
            # 既有正常记录又有跨月记录的情况
            result_lines = [f"### 查询成功，共找到{result_count}条发票记录（{start_date}至{end_date}），另外还有{cross_month_count}条跨月记录可能相关："]
            result_lines.append("\n#### 跨月记录列表：")
            
            # 构建跨月记录的简要信息
            for idx, invoice in enumerate(cross_month_invoice_list, 1):
                invoice_no = invoice.get('invoiceNo', '未知')
                invoice_end_date = invoice.get('endDate', '未知')
                amount_with_tax = invoice.get('amountWithTax', '0')
                result_lines.append(f"{idx}. 发票编号：{invoice_no}，结束日期：{invoice_end_date}，含税金额：{amount_with_tax}元")
            
            result_lines.append("\n是否需要包含这些跨月记录？请回复'是'或'否'")
        elif result_count > 0 and cross_month_count == 0:
            # 只有正常记录的情况
            result_lines = [f"### 查询成功，共找到{result_count}条发票记录（{start_date}至{end_date}）"]
        
        # 如果用户要求数据分析，则显示数据分析模式的提示信息
        if do_analysis or do_chart:
            result_lines = [f"### 数据分析结果"]
    
    # 构建响应对象
    response = {
        "user_query": user_query,
        "summary": "\n".join(result_lines) if result_lines else ("数据分析结果" if do_analysis or do_chart else ""),
        "records": records if not (do_analysis or do_chart) else [],  # 分开问时只返回查询数据
        "download_links": download_links if not (do_analysis or do_chart) else []  # 分开问时只返回下载链接
    }
    
    # 如果用户确认包含跨月记录，确保响应对象包含所有必要字段
    if include_cross_month and cross_month_count > 0:
        # 确保summary字段包含完整的查询结果信息
        if not result_lines:
            result_lines = [f"### 查询成功，共找到{len(records)}条发票记录（包含{cross_month_count}条跨月记录）"]
        response['summary'] = "\n".join(result_lines)
    
    # 添加跨月记录信息到响应中（仅在需要用户确认时）
    if cross_month_count > 0 and not include_cross_month:
        # 为跨月记录添加单位名称信息
        cross_month_records_with_unit = []
        for invoice in cross_month_invoice_list:
            # 创建记录副本并添加单位名称
            invoice_copy = invoice.copy()
            invoice_copy['unit_name'] = unit_name  # 添加单位名称字段
            cross_month_records_with_unit.append(invoice_copy)
        
        response["cross_month_records"] = cross_month_records_with_unit  # 添加跨月记录信息
        
        # 添加用户确认标记，表示需要用户确认是否包含跨月记录
        response["needs_cross_month_confirmation"] = True
        
        # 如果生成了跨月确认询问，立即保存到对话历史中
        if result_lines and "是否需要包含这些跨月记录" in "\n".join(result_lines):
            # 保存助手消息到对话历史
            chat_history_manager.add_message(conversation_id, "assistant", "\n".join(result_lines))
            logging.info("[对话管理] 已保存跨月确认询问到对话历史")
    
    # 仅在用户没有要求分析或画图时返回趋势分析字段
    if not do_analysis and not do_chart:
        response["extend_question"] = "对数据进行趋势分析和可视化"
    
    # 只有在生成了分析结果时才包含analysis字段
    if text_analysis:
        response["analysis"] = text_analysis
    
    # 只有在生成了趋势图时才包含chart字段
    if trend_data and "trend_chart" in trend_data:
        response["chart"] = trend_data["trend_chart"]
    if debug:
        response["debug_info"] = {
            "generated_params": params,
            "target_api_url": f"{Config.TARGET_API_BASE_URL}{Config.INVOICE_API_PATH}",
            "raw_response": data
        }
    end_time = time.time()
    logging.info(f"[步骤5-发票数据处理] 处理发票数据耗时: {end_time - start_time:.2f}秒")
    return response

# 封装函数，类似Dify服务
async def call_invoice_service(user_query: str, phone_number: str, conversation_id: Optional[str] = None, debug: bool = False, include_analysis: Optional[bool] = None, include_chart: Optional[bool] = None, is_monitor: bool = False, params: Optional[dict] = None) -> dict:
    start_time = time.time()
    
    # 如果是监控请求，添加特殊标识到查询中，确保每次都是真实调用
    if is_monitor:
        monitor_tag = f"[MONITOR_{int(time.time())}]"
        user_query = f"{monitor_tag} {user_query}"
        logging.info(f"[步骤2-发票服务调用] 监控模式调用发票服务，已添加监控标识")
    
    logging.info(f"[步骤2-发票服务调用] 开始调用发票服务")
    # 如果传入了conversation_id，则使用它；否则创建一个新的本地对话ID
    local_conversation_id = conversation_id if conversation_id else chat_history_manager.create_new_conversation()
    logging.info(f"[对话管理] 使用对话ID: {local_conversation_id}")
    
    # 获取对话历史
    history = chat_history_manager.get_history(local_conversation_id)
    logging.info(f"[对话管理] 历史消息数量: {len(history)}")
    if history:
        logging.info(f"[对话管理] 最近一条历史消息: {history[-1]['content'][:50]}...")
    
    # 检查是否为用户选择单位的响应（处理模糊查询后的用户选择）
    is_user_selection = False
    selected_unit_info = None
    
    # 检查用户查询是否为数字选择（1-5）
    if user_query.strip().isdigit() and 1 <= int(user_query.strip()) <= 5:
        # 检查历史中是否有模糊查询的响应
        for msg in reversed(history):
            if msg.get("role") == "assistant" and "相似的单位" in msg.get("content", ""):
                # 当用户输入数字时，直接执行用户选择逻辑，不进行重复匹配检查
                is_user_selection = True
                selection_index = int(user_query.strip()) - 1
                logging.info(f"[用户选择] 检测到用户选择第{user_query.strip()}个单位，直接执行用户选择逻辑")
                
                # 从历史中提取相似单位列表
                import re
                content = msg.get("content", "")
                
                # 使用大模型理解历史对话中的序号对应关系
                logging.info(f"[用户选择] 使用大模型处理用户选择第{selection_index + 1}个单位")
                
                try:
                    from utils import get_user_available_units
                    available_units = await get_user_available_units(phone_number, return_full_info=True)
                    
                    # 使用大模型理解历史对话中的序号对应关系
                    selected_unit_info = await _llm_understand_selection(content, selection_index, available_units)
                    
                    if selected_unit_info:
                        unit_full_name = selected_unit_info.get("unitFullName", "未知单位")
                        unit_id = selected_unit_info.get("unitId")
                        logging.info(f"[用户选择] 用户选择单位匹配成功: {unit_full_name} (ID: {unit_id})")
                        logging.info(f"[单位匹配完成] 用户选择单位匹配完成: {unit_full_name}")
                    else:
                        logging.warning(f"[用户选择] 大模型未找到索引为{selection_index}的单位")
                        
                except Exception as e:
                    logging.error(f"[用户选择] 处理用户选择失败: {str(e)}")
                
                break
    
    # 参数处理优先级：用户选择单位 > 外部传入参数 > 自动参数转换
    if is_user_selection and selected_unit_info:
        # 用户选择了单位，优先使用用户选择的信息
        logging.info(f"[参数转换] 处理用户选择的单位: {selected_unit_info.get('unitFullName', '未知单位')}")
        
        # 构建基础参数
        params = {
            "unitId": selected_unit_info.get("unitId"),
            "phoneNo": phone_number
        }
        
        # 添加时间参数（使用默认时间范围或从历史中提取）
        try:
            from utils import extract_time_params_from_history
            time_params = await extract_time_params_from_history(history)
            
            # 检查时间参数的置信度，只有在置信度较高时才使用
            confidence = time_params.get("confidence", 0.0)
            if time_params.get("startDate") and time_params.get("endDate") and confidence > 0.7:
                params["startDate"] = time_params["startDate"].replace("-", "")
                params["endDate"] = time_params["endDate"].replace("-", "")
                logging.info(f"[参数转换] 从历史中提取时间参数（置信度{confidence:.2f}）: {params['startDate']} 至 {params['endDate']}")
            else:
                    # 使用智能默认时间范围
                    from datetime import datetime, timedelta
                    today = datetime.now()
                    
                    # 检查当前用户查询是否包含时间关键词
                    current_user_query = user_query if user_query else ""
                    time_keywords = ['今天', '昨天', '本周', '上周', '本月', '上月', '今年', '去年', 
                                   '年', '月', '日', '号', '周', '季度', '上半年', '下半年']
                    has_time_keywords = any(keyword in current_user_query for keyword in time_keywords)
                    
                    if has_time_keywords:
                        # 如果用户查询包含时间关键词，使用更短的时间范围（最近7天）
                        end_date = today.strftime("%Y%m%d")
                        start_date = (today - timedelta(days=7)).strftime("%Y%m%d")
                        logging.info(f"[参数转换] 用户查询包含时间关键词，使用最近7天时间范围: {start_date} 至 {end_date}")
                    else:
                        # 默认使用最近3个月时间范围（基于月份计算，而非固定90天）
                        # 发票API期望的是YYYYMMDD格式的日期参数，但会识别为当月第一天
                        end_date = today.strftime("%Y%m01")  # 当月第一天
                        # 计算3个月前的月份第一天
                        start_year = today.year
                        start_month = today.month - 3
                        if start_month <= 0:
                            start_year -= 1
                            start_month += 12
                        start_date = f"{start_year:04d}{start_month:02d}01"  # 3个月前月份第一天
                        logging.info(f"[参数转换] 使用默认时间参数（最近3个月）: {start_date} 至 {end_date}")
                    
                    params["startDate"] = start_date
                    params["endDate"] = end_date
        except Exception as e:
            logging.error(f"[参数转换] 提取时间参数失败: {str(e)}")
            # 使用默认时间范围（最近3个月）
            from datetime import datetime
            today = datetime.now()
            # 发票API期望的是YYYYMMDD格式的日期参数，但会识别为当月第一天
            end_date = today.strftime("%Y%m01")  # 当月第一天
            # 计算3个月前的月份第一天
            start_year = today.year
            start_month = today.month - 3
            if start_month <= 0:
                start_year -= 1
                start_month += 12
            start_date = f"{start_year:04d}{start_month:02d}01"  # 3个月前月份第一天
            params["startDate"] = start_date
            params["endDate"] = end_date
            logging.info(f"[参数转换] 异常处理，使用默认时间参数: {start_date} 至 {end_date}")
        
        validated_params = UnitDateParams(**params).dict()
        logging.info(f"[参数转换] 用户选择单位后的完整参数: {validated_params}")
    elif params is not None:
        # 使用外部传入的参数（但用户未选择单位时）
        logging.info(f"[参数转换] 使用外部传入的发票查询参数: {params}")
        # 确保params中包含手机号
        if 'phoneNo' not in params and phone_number:
            params['phoneNo'] = phone_number
        validated_params = UnitDateParams(**params).dict()
    else:
        # 非用户选择模式，调用convert_params进行参数转换
        # 注意：convert_params函数内部会进行单位匹配，避免与用户选择逻辑重复
        params = await convert_params(user_query, "invoice", phone_number, history, is_user_selection, selected_unit_info)
        logging.info(f"[参数转换] 发票查询参数: {params}")
        
        # 检查是否为模糊关键词处理结果
        if isinstance(params, dict) and params.get('is_ambiguous_keyword'):
            # 如果是模糊关键词，直接返回反问消息
            logging.info(f"[参数转换] 检测到模糊关键词，返回反问消息")
            ambiguous_response = params.get('ambiguous_response', {})
            
            # 保存对话记录到本地对话ID中
            chat_history_manager.add_message(local_conversation_id, "user", user_query)
            chat_history_manager.add_message(local_conversation_id, "assistant", ambiguous_response.get('response_message', ''))
            
            # 构建与普通查询结果一致的返回格式
            result = {
                "user_query": user_query,
                "summary": ambiguous_response.get('response_message', ''),
                "records": [],
                "download_links": [],
                "extend_question": ""
            }
            
            return {
                "answer": ambiguous_response.get('response_message', ''),
                "conversation_id": local_conversation_id,
                "result": result
            }
        
        validated_params = UnitDateParams(**params).dict()
    
    # 确保validated_params中包含手机号
    if 'phoneNo' not in validated_params and phone_number:
        validated_params['phoneNo'] = phone_number
    
    # 检查是否为跨月记录确认响应（"是"或"否"）
    is_cross_month_confirmation = False
    cross_month_confirmation = None
    
    # 检查用户查询是否为跨月记录确认
    # 首先检查对话历史中是否有跨月确认的询问
    has_cross_month_question = False
    for msg in reversed(history):
        if msg.get("role") == "assistant" and "是否需要包含这些跨月记录" in msg.get("content", ""):
            has_cross_month_question = True
            break
    
    # 只有当历史中有跨月确认询问时，才将用户的简单响应识别为跨月确认
    if has_cross_month_question:
        if user_query.strip().lower() in ['是', 'yes', 'y', 'true', '1']:
            logging.info("[跨月确认] 用户确认包含跨月记录")
            is_cross_month_confirmation = True
            cross_month_confirmation = True
        elif user_query.strip().lower() in ['否', 'no', 'n', 'false', '0']:
            logging.info("[跨月确认] 用户拒绝包含跨月记录")
            is_cross_month_confirmation = True
            cross_month_confirmation = False
    else:
        logging.info("[跨月确认] 对话历史中没有跨月确认询问，不将用户响应识别为跨月确认")
    
    # 如果用户确认了跨月记录，重新处理数据
    if is_cross_month_confirmation:
        logging.info("[跨月确认] 重新处理发票数据以包含跨月记录")
        
        # 首先需要调用API获取数据
        data = await service.call_api(Config.INVOICE_API_PATH, validated_params)
        
        # 确保data是字典类型
        if not isinstance(data, dict):
            logging.error(f"[API调用] 发票API返回类型错误，期望字典但得到: {type(data)}")
            raise HTTPException(status_code=500, detail="API返回数据格式错误")
        
        logging.info(f"[API调用] 发票数据获取成功: {len(data.get('invoiceList', []))}条记录")
        
        # 重新调用process_invoice_data，但这次包含跨月记录
        response = await process_invoice_data(
            data=data,
            debug=debug,
            user_query=user_query,
            params=validated_params,
            conversation_id=local_conversation_id,
            include_analysis=include_analysis,
            include_chart=include_chart,
            include_cross_month=cross_month_confirmation  # 根据用户确认设置
        )
        
        # 保存对话记录到本地对话ID中
        chat_history_manager.add_message(local_conversation_id, "user", user_query)
        chat_history_manager.add_message(local_conversation_id, "assistant", response.get("summary", ""))
        
        # 构建与普通查询结果一致的返回格式
        # 创建result对象的深拷贝，避免修改原始response对象
        import copy
        result = copy.deepcopy(response)
        
        # 移除跨月确认相关的字段，避免前端解析失败
        if "cross_month_records" in result:
            del result["cross_month_records"]
        if "needs_cross_month_confirmation" in result:
            del result["needs_cross_month_confirmation"]
        
        return {
            "answer": result.get("summary", ""),
            "conversation_id": local_conversation_id,
            "result": result
        }
    
    data = await service.call_api(Config.INVOICE_API_PATH, validated_params)
    
    # 确保data是字典类型
    if not isinstance(data, dict):
        logging.error(f"[API调用] 发票API返回类型错误，期望字典但得到: {type(data)}")
        raise HTTPException(status_code=500, detail="API返回数据格式错误")
    
    logging.info(f"[API调用] 发票数据获取成功: {len(data.get('invoiceList', []))}条记录")
    
    # 直接处理发票数据，不进行额外的过滤
    result = await process_invoice_data(data, debug, user_query, validated_params, local_conversation_id, include_analysis, include_chart)
    
    # 检查查询结果是否为0条，如果是则进行扩展查询
    # 但需要排除有跨月记录的情况（跨月记录需要用户确认）
    has_cross_month_records = result.get("cross_month_records") and len(result.get("cross_month_records", [])) > 0
    
    if len(data.get('invoiceList', [])) == 0 and not has_cross_month_records:
        try:
            from utils_1 import enhance_no_data_response
            result = await enhance_no_data_response(
                result, validated_params, Config.INVOICE_API_PATH, "invoice", service, user_query
            )
            logging.info("[发票服务] 已应用扩展查询功能")
        except Exception as e:
            logging.warning(f"[发票服务] 扩展查询功能执行失败: {str(e)}")
            # 扩展查询失败不影响主流程，继续使用原始结果
    
    # 保存对话记录到本地对话ID中
    chat_history_manager.add_message(local_conversation_id, "user", user_query)
    chat_history_manager.add_message(local_conversation_id, "assistant", result.get("summary", ""))
    
    end_time = time.time()
    logging.info(f"[步骤2-发票服务调用] 调用发票服务耗时: {end_time - start_time:.2f}秒")
    return {
        "answer": result.get("summary", ""),
        "conversation_id": local_conversation_id,
        "result": result
    }